package com.cfets.annualAssessment.securityConfig;

import com.cfets.annualAssessment.filter.MyFilterSecurityInterceptor;
import com.cfets.annualAssessment.filter.SimpleCORSFilter;
import com.cfets.annualAssessment.util.Constant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.access.channel.ChannelProcessingFilter;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

/**
 * Created with WebSecurityConfig
 * User: pual
 * Date: 2016/10/12
 * Desc:
 */
//@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity
@Order(SecurityProperties.BASIC_AUTH_ORDER+1)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired private UserDetailsService userDetailsService;
    @Autowired private PasswordEncoder passwordEncoder;
    @Autowired private MyFilterSecurityInterceptor myFilterSecurityInterceptor;
//    @Autowired
//    AuthenticationManager authenticationManager;
//    @Autowired private SimpleCORSFilter simpleCORSFilter;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
    }

    @Override
    public void configure(final WebSecurity web) throws Exception {
        final HttpSecurity http = getHttp();
        web.postBuildAction(new Runnable() {
            @Override
            public void run() {
                web.securityInterceptor(http.getSharedObject(FilterSecurityInterceptor.class));
            }
        });
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/static/**").permitAll();
        http.csrf().ignoringAntMatchers("/admin/**/restful/**")
                .ignoringAntMatchers("/admin/**/restful")
                .ignoringAntMatchers("/admin/**/import")
                .ignoringAntMatchers("/admin/**/Get");
        http.authorizeRequests()
//                .antMatchers("/admin/demo/**").permitAll()
                .antMatchers("/admin/**/restful").permitAll()
                .antMatchers("/admin/**/restful/**").permitAll()
                .antMatchers("/admin/wx/**").permitAll()
                .antMatchers("/admin/login").permitAll()
//                .antMatchers("/users/**").hasAuthority("ADMIN")
                .anyRequest().fullyAuthenticated()
                .and()
                .formLogin()
                .loginPage("/admin/login")
                .failureUrl("/admin/login?error").defaultSuccessUrl("/admin/home/index")
                .usernameParameter("accountName").passwordParameter("password")
                .permitAll()
                .and()
                .logout()
                .logoutUrl("/admin/logout")
                .deleteCookies("remember-me")
                .logoutSuccessUrl("/admin/login")
                .permitAll()
                .and().addFilterBefore(myFilterSecurityInterceptor,FilterSecurityInterceptor.class)
                .addFilterBefore(new SimpleCORSFilter(),ChannelProcessingFilter.class)//spring security cors
                .rememberMe();
        http.addFilterBefore(myUsernamePasswordAuthenticationFilter(),MyUsernamePasswordAuthenticationFilter.class);
    }

//    http.csrf().disable().addFilterBefore(new SimpleCORSFilter(),ChannelProcessingFilter.class).authorizeRequests()
//                .antMatchers("/rest/**").permitAll()
//                .anyRequest().authenticated()
//                .and().formLogin().loginPage("/admin/login")
//                .passwordParameter("password").usernameParameter("accountName").permitAll().and()
//                .httpBasic();
//    }
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
    @Bean
    MyUsernamePasswordAuthenticationFilter myUsernamePasswordAuthenticationFilter() throws Exception {
        MyUsernamePasswordAuthenticationFilter myUsernamePasswordAuthenticationFilter = new MyUsernamePasswordAuthenticationFilter();
        AntPathRequestMatcher antPathRequestMatcher = new AntPathRequestMatcher("/admin/login", "POST");
        MyAuthenticationSuccessHandler myAuthenticationSuccessHandler = new MyAuthenticationSuccessHandler("/admin/home/index");
        MyAuthenticationFailureHandler myAuthenticationFailureHandler = new MyAuthenticationFailureHandler("/admin/login?error");
        myUsernamePasswordAuthenticationFilter.setAuthenticationManager(authenticationManagerBean());
        myUsernamePasswordAuthenticationFilter.setPasswordParameter("password");
        myUsernamePasswordAuthenticationFilter.setUsernameParameter("accountName");
        myUsernamePasswordAuthenticationFilter.setRequiresAuthenticationRequestMatcher(antPathRequestMatcher);
        myUsernamePasswordAuthenticationFilter.setAuthenticationSuccessHandler(myAuthenticationSuccessHandler);
        myUsernamePasswordAuthenticationFilter.setAuthenticationFailureHandler(myAuthenticationFailureHandler);
        return myUsernamePasswordAuthenticationFilter;
    }
}
